//package com.imooc.pan.server.common.listener.file;
//
//import com.alibaba.fastjson.JSON;
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.baomidou.mybatisplus.core.toolkit.Wrappers;
//import com.imooc.pan.core.constants.RPanConstants;
//import com.imooc.pan.server.common.event.file.FilePhysicalDeleteEvent;
//import com.imooc.pan.server.common.event.log.ErrorLogEvent;
//import com.imooc.pan.server.modules.file.entity.RPanFile;
//import com.imooc.pan.server.modules.file.entity.RPanUserFile;
//import com.imooc.pan.server.modules.file.enums.FolderFlagEnum;
//import com.imooc.pan.server.modules.file.service.IFileService;
//import com.imooc.pan.server.modules.file.service.IUserFileService;
//import com.imooc.pan.storage.engine.core.StorageEngine;
//import com.imooc.pan.storage.engine.core.context.DeleteFileContext;
//import org.apache.commons.collections.CollectionUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.ApplicationContext;
//import org.springframework.context.ApplicationContextAware;
//import org.springframework.context.event.EventListener;
//import org.springframework.scheduling.annotation.Async;
//import org.springframework.stereotype.Component;
//
//import java.io.IOException;
//import java.util.List;
//import java.util.Objects;
//import java.util.stream.Collectors;
//
///**
// *
// */
//@Component
//public class FilePhysicalDeleteEventListener implements ApplicationContextAware {
//
//    @Autowired
//    private IFileService iFileService;
//
//    @Autowired
//    private IUserFileService iUserFileService;
//
//    @Autowired
//    private StorageEngine storageEngine;
//
//    private ApplicationContext applicationContext;
//
//    @Override
//    public void setApplicationContext(ApplicationContext applicationContext) {
//        this.applicationContext = applicationContext;
//    }
//
//
//    /**
//     * 1、查询所有无引用的实体文件记录，回收站中也没有了
//     * 2、删除记录
//     * 3、物理清除文件
//     *
//     * @param event
//     */
//    @EventListener(classes = FilePhysicalDeleteEvent.class)
//    @Async(value = "eventListenerTaskExecutor")
//    public void physicalDeleteFile(FilePhysicalDeleteEvent event) {
//        // 实现逻辑
//        List<RPanUserFile> allRecords = event.getAllRecords();
//        if (CollectionUtils.isEmpty(allRecords)) {
//            return;
//        }
//        List<Long> realFileIdList = findAllUnusedRealFileIdList(allRecords);
//        List<RPanFile> realFileRecords = iFileService.listByIds(realFileIdList);
//        if (!iFileService.removeByIds(realFileIdList)) {
//            applicationContext.publishEvent(new ErrorLogEvent(this,
//                    JSON.toJSONString("实体文件记录" + realFileIdList + "物理删除失败，请手动删除"),
//                    RPanConstants.ZERO_LONG));
//        }
//        physicalDeleteFileByStorageEngine(realFileRecords); // 委托存储引擎删除实体文件
//    }
//
//    private void physicalDeleteFileByStorageEngine(List<RPanFile> realFileRecords) {
//        List<String> realPathList = realFileRecords.stream().map(RPanFile::getRealPath).collect(Collectors.toList());
//        DeleteFileContext deleteFileContext = new DeleteFileContext();
//        deleteFileContext.setRealFilePathList(realPathList);
//        try {
//            storageEngine.delete(deleteFileContext);
//        } catch (IOException e) {
//            applicationContext.publishEvent(new ErrorLogEvent(this,
//                    JSON.toJSONString("实体文件记录" + realPathList + "物理删除失败，请手动删除"),
//                    RPanConstants.ZERO_LONG));
//        }
//    }
//
//    private List<Long> findAllUnusedRealFileIdList(List<RPanUserFile> allRecords) {
//        List<Long> realFileIdList = allRecords
//                .stream()
//                .filter(record -> Objects.equals(record.getFolderFlag(), FolderFlagEnum.NO.getCode()))
//                .filter(this::isUnused).map(RPanUserFile::getFileId)
//                .collect(Collectors.toList());
//        return realFileIdList;
//    }
//
//    /**
//     * 校验文件的真实文件是不是没有被引用了
//     *
//     * @param record
//     * @return
//     */
//    private boolean isUnused(RPanUserFile record) {
//        // 校验文件的真实 id
//        QueryWrapper<RPanUserFile> queryWrapper = Wrappers.query();
//        queryWrapper.eq("real_file_id", record.getRealFileId());
//        return iUserFileService.count(queryWrapper) == RPanConstants.ZERO_INT;
//    }
//}
